#include <Arduino.h>
#include <ESP8266WiFi.h>
#include "PubSubClient.h"
#include <SoftwareSerial.h>
#include "bemfa.h"
#include "bemfa_ac.h"
#include "IRac.h"
#include "smart_wifi.h"
#include "decode_type.h"
#include "config.h"

#define IR_SEND_PIN 0

decode_type_t last_type = decode_type_t::UNKNOWN;
char *last_payload;
int16_t last_type_index = -1;

std::vector<uint16_t> search_invalid_indexs = {};
bool search_ac_state = false;
uint16_t search_group_index = 0;
int16_t search_first_group_index = -1;
unsigned long search_prev_time = 0;

const char *mqtt_server = "bemfa.com"; // 默认，MQTT服务器
const int mqtt_server_port = 9501;     // 默认，MQTT服务器

PubSubClient mqttClient(wifiClient);
IRac ir(IR_SEND_PIN);
SmartWifi smartWifi(LED_BUILTIN, true);

SoftwareSerial ASRPROSerial(1, 3);

bool control_ac(const char *payload)
{
  bemfa_payload_t state(last_payload);
  state.set(payload);
  state.getPayload(last_payload);
  ir.sendAc(
      last_type,
      (int16_t)-1,
      state.power,
      state.mode,
      state.degrees,
      true,
      state.fanspeed,
      state.swing_v,
      state.swing_h,
      true, false, state.econo,
      state.light, false, false, state.beep,
      state.getSleep(), (int16_t)-1);
  smartWifi.led.blink();
  writeData(last_type_index, last_payload);
  return true;
}
void search_ac_stop()
{
  if (!search_ac_state)
  {
    return;
  }
  search_ac_state = false;
  search_group_index = 0;
  search_first_group_index = -1;
}

void search_ac_start()
{
  search_ac_state = true;
  search_group_index = 0;
  search_first_group_index = -1;
  last_type_index = -1;
  search_invalid_indexs.clear();
}

void search_ac_loop()
{
  if (!search_ac_state)
  {
    return;
  }
  size_t size = ac_brands.size();
  if (search_group_index >= size)
  {
    search_ac_stop();
    return;
  }

  uint16_t current_group_index = search_group_index;
  if (search_first_group_index > -1)
  {
    current_group_index = search_first_group_index;
  }
  if (last_type_index > -1 && !array_find(search_invalid_indexs, last_type_index))
  {
    search_invalid_indexs.push_back(last_type_index);
  }

  int16_t index = find_ac_index(current_group_index, search_invalid_indexs);
  if (index == -1)
  {
    if (search_first_group_index != -1)
    {
      search_first_group_index = -1;
    }
    else
    {
      search_group_index++;
    }

    return;
  }
  if (millis() - search_prev_time < 2000)
  {
    return;
  }
  search_prev_time = millis();

  last_type_index = index;
  Serial.print("last_type_index: ");
  Serial.println(last_type_index);
  last_type = decodeTypeList[(int)last_type_index];
  control_ac("on#1#22");
}

bool parse_cmd_str(const char *command, const char *prefix, String &cmd)
{
  if (strncmp(command, prefix, strlen(prefix)) != 0)
  {
    return false;
  }
  // 查找 '#' 字符的位置
  char *hashPos = strchr(command, '#');

  // 确保 '#' 字符存在且不是命令的第一个字符（即不是 "#something" 的形式）
  if (hashPos == nullptr || hashPos == command)
  {
    return false;
  }
  cmd = String(hashPos + 1);
  return true;
}

bool search_ac(const char *command)
{
  String cmd;
  if (!parse_cmd_str(command, "search", cmd))
  {
    return false;
  }

  if (cmd == "start")
  {
    search_ac_start();
  }
  else if (cmd == "stop")
  {
    search_ac_stop();
  }
  else
  {
    int index = -1;
    if (isNumber(cmd))
    {
      index = atoi(cmd.c_str());
    }
    else
    {
      index = findIndexByBrand(cmd);
    }
    if (index == -1)
    {
      return false;
    }
    search_first_group_index = index;
  }
  return true;
}

bool control_led(const char *command)
{
  String cmd;
  if (!parse_cmd_str(command, "led", cmd))
  {
    return false;
  }
  String cmd_array[5];
  splitCommand(cmd, cmd_array);

  if (cmd_array[0] == "on")
  {
    smartWifi.led.on();
  }
  else if (cmd_array[0] == "off")
  {
    smartWifi.led.off();
  }
  else if (cmd_array[0] == "toggle")
  {
    smartWifi.led.toggle();
  }
  else if (cmd_array[0] == "blink")
  {
    int t = 1, ms = 100, c = true;
    if (cmd_array[1] != NULL)
    {
      t = atoi(cmd_array[1].c_str());
    }
    if (cmd_array[2] != NULL)
    {
      ms = atoi(cmd_array[2].c_str());
    }
    if (cmd_array[3] != NULL)
    {
      c = !!atoi(cmd_array[3].c_str());
    }
    smartWifi.led.blink(t, ms, c);
  }
  return true;
}

void local_command(const char *command)
{
  search_ac(command) || control_led(command) || control_ac(command);
}

void callback(char *topic, byte *buffer, unsigned int len)
{
  char payload[len + 1];
  for (size_t i = 0; i < len; ++i)
  {
    payload[i] = buffer[i];
  }
  payload[len] = '\0';
  local_command(payload);
}

void reconnect()
{
  smartWifi.led.on();
  while (!mqttClient.connected())
  {
    if (mqttClient.connect(ID_MQTT))
    {
      mqttClient.setCallback(callback);
      mqttClient.subscribe(TOPIC);
    }
    else
    {
      smartWifi.led.toggle();
      delay(5000);
    }
  }
  smartWifi.led.off();
}

void parse_input(String input)
{
  input.trim();
  String input_array[2];
  splitCommand(input, input_array, "@");
  if (input_array[1] == NULL)
  {
    local_command(input_array[0].c_str());
  }
  else
  {
    mqttClient.publish(input_array[0].c_str(), input_array[1].c_str());
    smartWifi.led.blink();
  }
}

void setup()
{
  ASRPROSerial.begin(9600);
  // 调试时打开
  // Serial.begin(9600);
  smartWifi.begin();
  mqttClient.setServer(mqtt_server, mqtt_server_port); // 设置mqtt服务器
  smartWifi.led.blink(3);

  readData(last_type_index, last_payload);
  if (!last_payload)
  {
    bemfa_payload_t state;
    state.getPayload(last_payload);
  }
  last_type = decodeTypeList[last_type_index];

  // Serial.print("init last:");
  // Serial.print(last_type_index);
  // Serial.print(" -- ");
  // Serial.println(last_payload);
}

void loop()
{
  if (!mqttClient.connected())
  {
    reconnect();
  }
  mqttClient.loop();

  search_ac_loop();

  if (ASRPROSerial.available())
  {
    parse_input(ASRPROSerial.readStringUntil('\n'));
  }

  if (Serial.available())
  {
    parse_input(Serial.readStringUntil('\n'));
  }
}
